﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using FW;
using System.Configuration;

namespace Kcadastro.classes
{
    public class oss
    {
        private fwlog log = (fwlog)ConfigurationManager.GetSection("fwlog");
        
        kcadDataContext db = new kcadDataContext(ConfigurationManager.ConnectionStrings["KcadConnectionString"].ToString());

        //private int _idos;
        private string _msg;


        /*
         * Status da OS
         * 1 - aberta
         * 2 - 
         * 3 - agendada para consulta
         * 4 - rodando
         * 5 - agendada reconsulta
         * 6 - cancelada thread
         * 9 - agendada fechamento
         * 10 - finalizada
         * 90 - cancelada usuario
         */

        public oss()
        { 
            
        }

        public List<tb_o> listOss(int _idemp)
        {
            List<tb_o> ret = new List<tb_o>();

            ret = (from tb in db.tb_os
                   where tb.FK_IDemp == _idemp
                   orderby tb.dt_reg descending
                   select tb).ToList<tb_o>();

            return ret;
        
        }

        public tb_o getNumOs(int _idOS)
        {
            tb_o ret = new tb_o();

            ret = db.tb_os.FirstOrDefault(o=>o.PK_IDos == _idOS) ;

            return ret;

        }

        public int abrirOS(tb_o _o)
        {
            int ret = 0;


            db.tb_os.InsertOnSubmit(_o);
            db.SubmitChanges();

            ret = (int) _o.PK_IDos;

            cIO io = new cIO();
            io.CriaDir(ConfigurationManager.AppSettings["arqPath"].ToString() + _o.FK_IDemp.ToString() + "/" + ret.ToString());
            io.CriaDir(ConfigurationManager.AppSettings["arqPath"].ToString() + _o.FK_IDemp.ToString() + "/" + ret.ToString() + "/mp");
            io = null;

            return ret;
        }

        public void gravarReportErros(string _erros, string idos, string idemp)
        {
            cIO cio = new cIO();
            cio.NomeArquivo = ConfigurationManager.AppSettings["arqPath"].ToString() + idemp + "/" + idos + "/reportErros.txt";
            cio.Conteudo = _erros;
            cio.GravarArquivo();
            cio = null;
        }

        public IList<string> headArquivo(long __idos, string _arquivo)
        {
            IList<string> ret = new List<string>();
            string arq = _arquivo;
            cIO io = new cIO();
            io.NomeArquivo = arq;
            ret = io.Head("10");
            io = null;

            return ret;
        }

        public void updateArqOriginal(long __idos, string _caminho)
        {
            tb_o to = db.tb_os.Single(t=>t.PK_IDos == __idos);
            to.caminhoOriginal = _caminho;
            db.SubmitChanges();
            to = null;
        }

        public void gravarServicos(long __idos, int[] _idss, int _qtdregistros)
        {
            db.ExecuteCommand("delete from tb_osXserv where FK_IDos = {0}", __idos.ToString());
            db.SubmitChanges();
            tb_osXserv ti = new tb_osXserv();
            foreach (int ids in _idss)
            {
                ti = new tb_osXserv() { FK_IDos = __idos, FK_IDserv = ids, qtdregistros = _qtdregistros, orcamento = 0, qtdprocessada = 0 };
                db.tb_osXservs.InsertOnSubmit(ti);
                db.SubmitChanges();
            }

        }

        public List<tb_osXserv> lerServicos(long __idos)
        {
            List<tb_osXserv> ret = new List<tb_osXserv>();
            ret = (from tb in db.tb_osXservs
                                    where tb.FK_IDos == __idos
                                    select tb).ToList<tb_osXserv>();
            return ret;
        }

        public void updateOS(tb_o _o)
        {
            tb_o o = db.tb_os.Single(t => t.PK_IDos == _o.PK_IDos);
            o.agendadopara = _o.agendadopara;
            o.arquivoOK = _o.arquivoOK;
            //o.caminhoFinal = _o.caminhoFinal;
            //o.caminhoOriginal = _o.caminhoOriginal;
            o.nomeOS = _o.nomeOS;
            o.orcamentoOK = _o.orcamentoOK;
            o.pagaOK = _o.pagaOK;
            o.processando = _o.processando;
            o.qtd_processada = _o.qtd_processada;
            o.qtd_registros = _o.qtd_registros;
            o.status = _o.status;
            o.stts = _o.stts;
            o.terminoOK = _o.terminoOK;
            o.valorOrcamento = _o.valorOrcamento;
            if (_o.dt_proxExec != null)
            {
                if (_o.dt_proxExec != new DateTime(1,1,1))
                o.dt_proxExec = _o.dt_proxExec;
            }
            db.SubmitChanges();
            
        }

        public void uptNome(tb_o _tb)
        {
            tb_o tto = db.tb_os.Single(t => t.PK_IDos == _tb.PK_IDos);
            tto.nomeOS = _tb.nomeOS;
            db.SubmitChanges();
        }


        public tb_o lerOs(long __idos)
        {
            tb_o ret = new tb_o();
            ret = db.tb_os.Single(t => t.PK_IDos == __idos);

            return ret;
        }

        public List<tb_servico> listaServicos(int _tpps)
        {
            List<tb_servico> ret = (from tb in db.tb_servicos
                                    where tb.ativo == true
                                    && tb.tpps == _tpps
                                    orderby tb.PK_IDserv
                                    select tb).ToList<tb_servico>();
            return ret;
        }

        public void orcamento(long __idos)
        { 
            tb_o oos = db.tb_os.Single(t => t.PK_IDos == __idos);
            tb_empresa te = db.tb_empresas.Single(t => t.PK_IDemp == oos.FK_IDemp);

            switch (te.contratoTipo)
            { 
                case 1:
                    var oserv1 = (from tb in db.tb_osXservs
                         where tb.FK_IDos == __idos
                             select tb);
                    foreach (tb_osXserv tos in oserv1)
                    {
                        decimal preco = 0;
                        tb_preco tp = db.tb_precos.Single(t => t.FK_IDserv == tos.FK_IDserv);
                        if (oos.qtd_registros > tp.RegMinimo)
                        {
                            preco = (decimal)tp.franquia + ((decimal)((int) oos.qtd_registros - (int)tp.RegMinimo) * (decimal)tp.valorporregistro);
                            //preco = (decimal) db.tb_precos.Single(t => t.FK_IDserv == tos.FK_IDserv && t.qtdini <= tos.qtdregistros && t.qtdfim >= tos.qtdregistros).valorporregistro;
                        }
                        else
                        {
                            preco = (decimal)tp.franquia;
                        }
                        tb_osXserv tt = db.tb_osXservs.Single(t => t.PK_IDosxsr == tos.PK_IDosxsr);
                        tt.qtdregistros = (int) oos.qtd_registros;
                        tt.qtdprocessada = 0;
                        tt.orcamento = preco;
                        db.SubmitChanges();
                    }

            
                    oos.valorOrcamento = (decimal) oos.tb_osXservs.Where(t => t.FK_IDos == __idos).Sum(t => t.orcamento).Value;
                    db.SubmitChanges();

                    break;
                case 2: // ondemand
                     var oserv2 = (from tb in db.tb_osXservs
                         where tb.FK_IDos == __idos
                             select tb);
                    foreach (tb_osXserv tos in oserv2)
                    {
                        decimal preco = 0;
                        tb_preco tp = db.tb_precos.Single(t => t.FK_IDserv == tos.FK_IDserv);
                        if (oos.qtd_registros > tp.RegMinimo)
                        {
                            preco = (decimal)tp.franquia + ((decimal)((int) oos.qtd_registros - (int)tp.RegMinimo) * (decimal)tp.valorporregistro);
                            //preco = (decimal) db.tb_precos.Single(t => t.FK_IDserv == tos.FK_IDserv && t.qtdini <= tos.qtdregistros && t.qtdfim >= tos.qtdregistros).valorporregistro;
                        }
                        else
                        {
                            preco = (decimal)tp.franquia;
                        }
                        tb_osXserv tt = db.tb_osXservs.Single(t => t.PK_IDosxsr == tos.PK_IDosxsr);
                        tt.qtdregistros = (int) oos.qtd_registros;
                        tt.orcamento = preco;
                        db.SubmitChanges();
                    }

            
                    oos.valorOrcamento = (decimal) oos.tb_osXservs.Where(t => t.FK_IDos == __idos).Sum(t => t.orcamento).Value;
                    db.SubmitChanges();
                    break;
                case 3: // pre pago



                    break;
            }

            //var oserv = (from tb in db.tb_osXservs
            //             where tb.FK_IDos == __idos
            //                 select tb);
            //foreach (tb_osXserv tos in oserv)
            //{
            //    decimal preco = (decimal) db.tb_precos.Single(t => t.FK_IDserv == tos.FK_IDserv && t.qtdini <= tos.qtdregistros && t.qtdfim >= tos.qtdregistros).valorporregistro;
            //    tb_osXserv tt = db.tb_osXservs.Single(t => t.PK_IDosxsr == tos.PK_IDosxsr);
            //    tt.orcamento = preco * tos.qtdregistros;
            //    db.SubmitChanges();
            //}

            
            //oos.valorOrcamento = (decimal) oos.tb_osXservs.Sum(t => t.orcamento).Value;
            //db.SubmitChanges();

            
            //oserv = null;


        }

        public List<v_orcamento> listaOrcamento(long __idos)
        {
            List<v_orcamento> ret = (from tb in db.v_orcamentos
                                     where tb.PK_IDos == __idos
                                     select tb).ToList<v_orcamento>();
            return ret;
        }

        public List<ListaOS> agendamentos(int __stts)
        {
            List<ListaOS> ret;
            if (__stts != 0)
            {
                ret = (from tb in db.tb_os
                       from tbe in db.tb_empresas
                       from tbu in db.tb_usuarios
                       where tb.FK_IDemp == tbe.PK_IDemp
                       && tb.FK_IDuser == tbu.PK_IDuser
                       && tb.stts == __stts
                       orderby tb.PK_IDos ascending
                       select new ListaOS
                       {
                           DATAABERTURA = (DateTime)tb.dt_reg,
                           DTPROXEXEC = tb.dt_proxExec == null ? new DateTime(1901, 1, 1) : (DateTime)tb.dt_proxExec,
                           EMPRESA = tbe.RS,
                           PKIDOS = tb.PK_IDos,
                           QTDPROCESSADA = (long) tb.qtd_processada,
                           QTDREGISTROS = (long) tb.qtd_registros,
                           STATUS = Enum.GetName(typeof(STTS), (int)tb.stts),
                           STTS = (int) tb.stts,
                           TPPS = ((int)tb.tpps ) == 3 ? "PJ" : "PF",
                           USUARIO = tbu.nomecompleto
                       }
                      ).ToList<ListaOS>();
            }
            else
            {
                ret = (from tb in db.tb_os
                       from tbe in db.tb_empresas
                       from tbu in db.tb_usuarios
                       where tb.FK_IDemp == tbe.PK_IDemp
                       && tb.FK_IDuser == tbu.PK_IDuser
                       orderby tb.PK_IDos ascending
                       select new ListaOS
                       {
                           DATAABERTURA = (DateTime)tb.dt_reg,
                           DTPROXEXEC = tb.dt_proxExec == null ? new DateTime(1901, 1, 1) : (DateTime)tb.dt_proxExec,
                           EMPRESA = tbe.RS,
                           PKIDOS = tb.PK_IDos,
                           QTDPROCESSADA = (long)tb.qtd_processada,
                           QTDREGISTROS = (long)tb.qtd_registros,
                           STATUS = Enum.GetName(typeof(STTS),  (int)tb.stts) ,
                           STTS = (int)tb.stts,
                           TPPS = ((int)tb.tpps) == 3 ? "PJ" : "PF",
                           USUARIO = tbu.nomecompleto
                       }
                         ).ToList<ListaOS>();
            }

            return ret;
        }


        public List<ListaThread> listarThreads()
        {
            List<ListaThread> ret = (from tb in db.v_threads
                                     orderby tb.PK_IDt ascending
                                     select new ListaThread { 
                                     dt_inicio = (DateTime) tb.dt_inicio,
                                     EMPRESA = tb.RS,
                                     FK_IDos = (long) tb.FK_IDos,
                                     PK_IDt = tb.PK_IDt,
                                     QTDPROC = (long) tb.qtd,
                                     QTDREGS = (long) tb.qtd_registros,
                                     tipo = tb.tipo,
                                     stts = tb.stts
                                     }).ToList<ListaThread>();
            return ret;
        }

        public void pararThread(int _idth)
        {
            tb_thread tt = db.tb_threads.Single(t => t.PK_IDt == _idth);
            tt.stts = "CNL";
            db.SubmitChanges();
        }



    }

    public class ListaOS
    {
        public long PKIDOS { get; set; }
        public int STTS { get; set; }
        public string STATUS { get; set; }
        public string EMPRESA { get; set; }
        public string USUARIO { get; set; }
        public long QTDREGISTROS { get; set; }
        public long QTDPROCESSADA { get; set; }
        public DateTime DATAABERTURA { get; set; }
        public string TPPS { get; set; }
        public DateTime DTPROXEXEC { get; set; }


    }

    public class ListaThread
    {
        public int PK_IDt { get; set; }
        public string EMPRESA { get; set; }
        public long QTDPROC { get; set; }
        public long QTDREGS { get; set; }
        public long FK_IDos { get; set; }
        public DateTime dt_inicio { get; set; }
        public string stts { get; set; }
        public string tipo { get; set; }


    }

    public enum STTS
    { 
        ABERTURA = 1,
        APROVACAO = 2,
        AGENDADA = 3,
        EXECUTANDO = 4,
        REAGENDADA = 5,
        CANCELTHREAD = 6,
        CANCELFECHAMENTO = 7,
        FECHANDOARQUIVOS = 8,
        AGUARDANDOFECHAMENTO = 9,
        FINALIZADA = 10,
        COMPUTADA = 11,
        CANCELUSER = 90
    }
}